


import java.net.*;
import java.io.*;
import java.util.ArrayList;
import java.util.Scanner;


public class SepereServer {
	
	
	 public ServerSocket serverSocket = null;
	 ArrayList<Peer> peerList; //list of Peers currently connected to the server
	 ArrayList<aFile> fileList;//list of Files available to search on the server
	 ArrayList<User> userList; //list of Users who have registered with the server
	 BufferedReader input;
	 BufferedWriter output;
	 boolean listening = true;
	 boolean dist = false;

	 public SepereServer()
	 {
		 peerList = new ArrayList();
		 fileList = new ArrayList();
		 userList = new ArrayList();
	 }
	 
	 public synchronized void addPeer(Peer p)
	 {
		 peerList.add(p);
	 }
		
	 public synchronized void removePeer(InetAddress a)
	 {
		 for(int i=0;i<peerList.size();i++)
		 {
			 //lets remove that peer that is no longer here
			 if(a==peerList.get(i).ipAddress)
				 peerList.remove(i);
		 }
		 
	 }
	 
	 public synchronized void addFile(aFile f)
	 {
		 fileList.add(f);
	 }
	 
	 public synchronized void addUser(User u)
	 {
		 userList.add(u);
	 }
	 
	 public void startServer()
	 {
		 //need to read in the list of registered users from the user file
		 String curDir = System.getProperty("user.dir");
		 String dl="";
		 Scanner s=null;
		 System.out.println(curDir);
		 
     try {
    	 input =  new BufferedReader(new FileReader(curDir+"\\user.txt"));
    	 
    	 while((dl=input.readLine())!=null)
    	 {
    		 //read in the current registered users from the user file
    		s = new Scanner(dl).useDelimiter("\\s*;\\s*");
    		User newU = new User();
    		if(s.next().equals("class:User")){
 			newU.name = s.next();
 			newU.email = s.next();
 			newU.userID = s.next();
 			newU.currentIP = InetAddress.getByName(s.next().substring(1));
 			//newU.setHash(s.next().getBytes());
 			newU.pass=s.next();
 			System.out.println(newU.toString());
 			this.addUser(newU);}
    	 }
    	 input.close();
    	 output = new BufferedWriter(new FileWriter(curDir+"\\user.txt"));
         serverSocket = new ServerSocket(4444);
     } catch (IOException e) {
         System.err.println("Could not listen on port: 4444.");
         e.printStackTrace();
         System.exit(1);
     }

	 }
	 
	 public synchronized String search(Search s)
	 {
		 //this is where the search will take place
		 ArrayList<aFile> resultArray = new ArrayList();
		 //aFile[] resultArray = new aFile[fileList.size()];
		 String result="";
		 int matchFlag=0;
		 for(int i =0;i<fileList.size();i++)
		 {   
			 matchFlag=SearchAsst.sfcompare(s.searchHash,fileList.get(i).getHash()); 
			 if(matchFlag>0)
				 {
				 docRank.Rank(fileList.get(i),matchFlag);
				 resultArray.add(fileList.get(i));
				 }
		 }
		 for(int i =0;i<resultArray.size();i++)
			 result+=resultArray.get(i).toString()+byteToHex(resultArray.get(i).getHash())+"\n";
		 System.out.println(result);
		 return result;
	 }
	 
	 public synchronized String logIn(String name, String pass)
	 {
		 //loop through database of users and find out if this user exist
		 int i = 0;
		 User cUser;
		 while(i<userList.size())
		 {
			cUser = userList.get(i);
			if(cUser.userID.equals(name))
				if(cUser.pass.equals(pass))
				{
					return "Welcome "+cUser.name;
				}
			 i++;
		 }
		 return "Login Fail";
	 }
	 
	 //assigns a superPeer to each peer in the distributed approach
	 public synchronized Peer assignPeer()
	 {
		 Peer test;
		 //will do a simple round robin approach to distributing peers
		 for(int i=0;i<peerList.size();i++)
		 {
			 test=peerList.get(i);
			 if(test.superPeer)
			 {
				//test to make sure the superPeer has less then 10 connections
				 if(test.numConnections<10)
				{
					test.numConnections++;
					return test;
				}
			 }
		 }
		 return null; //this means that we need to make another superpeer
		
	 }
	 
	 public void quit()
	 {
		 //write out the new user file before we close
		 try {
			for(int i=0;i<userList.size();i++)
				output.write(userList.get(i).toString()+System.getProperty("line.separator"));
			output.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		System.exit(1);
	 }
	 
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		
		SepereServer spere = new SepereServer();
		//boolean listening = true;
		//Scanner in = new Scanner(System.in);
		spere.startServer();
		System.out.println("Listening on Port 4444");
		new infoThread(spere).start();
		try{
		while (spere.listening){
		    new sThread(spere.serverSocket.accept(), spere).start();
		}
		spere.serverSocket.close();
		}
		catch (IOException e) {
            System.err.println("Could not listen on port: 4444.");
            System.exit(-1);
        }
		System.out.println("Done !!");
		
		// TODO Auto-generated method stub

	}
	
	static String byteToHex(byte[] msg) {
		String result = "";
		for (int i = 0; i < msg.length; i++) {
			char highBits, LowBits;
			highBits = (char) ((msg[i] >>> 4) & 0xf);
			LowBits = (char) (msg[i] & 0xf);
			highBits = (char) ((highBits > 9) ? 'A' + (highBits - 10)
					: '0' + highBits);
			LowBits = (char) ((LowBits > 9) ? 'A' + (LowBits - 10)
					: '0' + LowBits);
			result += highBits;
			result += LowBits;
		}
		return result;
	}

}
